package com.ynunicom.midplatform.common.util;

import lombok.extern.slf4j.Slf4j;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 日期工具类
 *
 * @author duwei
 */
@Slf4j
public class DateUtil {

    private static String DEFAULT_FORMAT = "yyyy-MM-dd HH:mm:ss";
    private static String DATE_FORMAT = "yyyy-MM-dd";

    /**
     * 格式化日期
     *
     * @param date 日期对象
     * @return String 日期字符串
     */
    public static String format(Date date) {
        return format(date, DEFAULT_FORMAT);
    }

    public static String formatToDate(Date date) {
        return format(date, DATE_FORMAT);
    }

    /**
     * 根据格式将日期对象转换成日期字符串
     *
     * @param date  要转换的对象
     * @param style 格式字符串
     */
    public static String format(Date date, String style) {
        try {
            return new SimpleDateFormat(style).format(date);
        } catch (Exception e) {
            log.error("自定格式Date转换String出现异常!", e);
        }
        return null;
    }

    /**
     * 获取当年的第一天
     *
     * @return
     */
    public static Date getCurrYearFirst() {
        Calendar currCal = Calendar.getInstance();
        int currentYear = currCal.get(Calendar.YEAR);
        return getYearFirst(currentYear);
    }

    /**
     * 获取当年的最后一天
     *
     * @return
     */
    public static Date getCurrYearLast() {
        Calendar currCal = Calendar.getInstance();
        int currentYear = currCal.get(Calendar.YEAR);
        return getYearLast(currentYear);
    }

    /**
     * 获取某年第一天日期
     *
     * @param year 年份
     * @return Date
     */
    public static Date getYearFirst(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        return calendar.getTime();
    }

    /**
     * 获取某年最后一天日期
     *
     * @param year 年份
     * @return Date
     */
    public static Date getYearLast(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        calendar.roll(Calendar.DAY_OF_YEAR, -1);

        return calendar.getTime();
    }

    /**
     * 获取某年某月的最后一天
     *
     * @throws
     * @Title:getLastDayOfMonth
     * @Description:
     * @param:@param year
     * @param:@param month
     * @param:@return
     * @return:String
     */
    public static Date getLastDayOfMonth(int year, int month) {
        Calendar cal = Calendar.getInstance();
        //设置年份
        cal.set(Calendar.YEAR, year);
        //设置月份
        cal.set(Calendar.MONTH, month - 1);
        //获取某月最大天数
        int ofMonth = LocalDate.now()
                .withYear(year)
                .withMonth(month)
                .lengthOfMonth();
        //设置日历中月份的最大天数
        cal.set(Calendar.DAY_OF_MONTH, ofMonth);

        return cal.getTime();
    }

    public static void main(String[] args) {
        Date lastDayOfMonth = getLastDayOfMonth(2000, 2);
        System.out.println(formatToDate(lastDayOfMonth));
    }

    /**
     * 得到某年某月的第一天
     *
     * @param year
     * @param month
     * @return
     */
    public static Date getFirstDayOfMonth(int year, int month) {

        Calendar cal = Calendar.getInstance();

        cal.set(Calendar.YEAR, year);

        cal.set(Calendar.MONTH, month - 1);

        cal.set(Calendar.DAY_OF_MONTH, cal.getMinimum(Calendar.DATE));

        return cal.getTime();
    }


    public static Map getWeekDay() {
        Map<String, String> map = new HashMap<>();
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        //获取本周一的日期
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        map.put("mon", df.format(cal.getTime()));
        //这种输出的是上个星期周日的日期，因为老外那边把周日当成第一天
        cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        //增加一个星期，才是我们中国人理解的本周日的日期
        cal.add(Calendar.WEEK_OF_YEAR, 1);
        map.put("sun", df.format(cal.getTime()));
        return map;
    }

    public static Map getMonthDate() {
        Map<String, String> map = new HashMap<String, String>();
        // 获取Calendar
        Calendar calendar = Calendar.getInstance();
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        // 设置时间,当前时间不用设置
        calendar.set(Calendar.DATE, calendar.getActualMinimum(Calendar.DATE));
        map.put("monthF", format.format(calendar.getTime()));
        // 设置日期为本月最大日期
        calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DATE));
        // 打印
        map.put("monthL", format.format(calendar.getTime()));
        return map;
    }


    /**
     * 根据格式将日期字符串转换成日期对象
     *
     * @param dateString 要进行转换的日期字符串
     * @param style      格式字符串
     */
    public static Date parse(String dateString, String style) {
        Date value = null;
        try {
            value = new SimpleDateFormat(style).parse(dateString);
        } catch (ParseException e) {
            log.error("自定格式String转换Date出现异常!", e);
        }
        return value;
    }


    /**
     * 将日期字符串转换成日期对象
     *
     * @param dateString 要进行转换的日期字符串
     */
    public static Date parse(String dateString) {
        return parse(dateString, DEFAULT_FORMAT);
    }

    /**
     * 获取指定日期的凌晨 00:00:00
     *
     * @param date
     * @return
     */
    public static Date getDayBegin(Date date) {
        Calendar begin = Calendar.getInstance();
        if (null != date) {
            begin.setTime(date);
        }
        begin.set(Calendar.HOUR_OF_DAY, 0);
        begin.set(Calendar.MINUTE, 0);
        begin.set(Calendar.SECOND, 0);
        begin.set(Calendar.MILLISECOND, 0);
        return begin.getTime();
    }

    /**
     * 获取指定日期的结束时间点23:59:59
     *
     * @param date
     * @return
     */
    public static Date getDayEnd(Date date) {
        Calendar end = Calendar.getInstance();
        if (null != date) {
            end.setTime(date);
        }
        end.set(Calendar.HOUR_OF_DAY, 23);
        end.set(Calendar.MINUTE, 59);
        end.set(Calendar.SECOND, 59);
        end.set(Calendar.MILLISECOND, 999);
        return end.getTime();
    }

}